package com.warmheart.base.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.warmheart.base.dao.BaseDao;
import com.warmheart.base.entity.BaseEntity;
import com.warmheart.base.page.PageInfo;
import com.warmheart.base.service.IBaseService;
import com.warmheart.core.rs.model.GroupByCntResultModel;

/**
 * 
 * @ClassName: BaseService
 * @Description: SERVICE基本实现类
 * @author ZhangJianyang
 * @date 2025-06-16 09:37:02
 *
 * @param <T>
 */
public abstract class BaseService<T extends BaseEntity<?, ?>> implements IBaseService<T> {

    /**
     * 
     * @Title: getDao
     * @Description: 基础DAO
     * @author ZhangJianyang
     * @return
     */
    public abstract BaseDao<T> getDao();

    /**
     * 
     * @Title: queryById
     * @Description: 根据主键查询单条记录
     * @author ZhangJianyang
     * @param id
     * @return
     */
    @Override
    public T queryById(Integer id) {
        return this.getDao().queryById(id);
    }
    
    /**
     * 
     * @Title: queryByIds
     * @Description: 根据ID列表批量查询数据列表
     * @author ZhangJianyang
     * @param ids
     * @return
     */
    @Override
    public List<T> queryByIds(Integer[] ids) {
        return this.getDao().queryByIds(ids);
    }

    /**
     * 
     * @Title: queryByIdList
     * @Description: 根据ID列表批量查询数据列表
     * @author ZhangJianyang
     * @param idList
     * @return
     */
    @Override
    public List<T> queryByIdList(List<Integer> idList) {
        if (idList == null || idList.size() == 0) {
            return new ArrayList<T>();
        }
        return this.getDao().queryByIds(idList.stream().toArray(Integer[]::new));
    }
    
    /**
     * 
     * @Title: selectInfoMapByIds
     * @Description: 根据ID列表批量查询数据列表
     * @author ZhangJianyang
     * @param ids
     * @return
     */
    @Override
    public Map<Integer, T> selectInfoMapByIds(Integer[] ids) {
        Map<Integer, T> infoMap = null;
        if (ids == null || ids.length == 0) {
            return new HashMap<Integer, T>();
        }
        List<T> list = this.getDao().queryByIds(ids);
        if (list != null && list.size() > 0) {
            infoMap = list.stream().collect(Collectors.toMap(T::getId, item -> item));
        }
        if (infoMap == null) {
            infoMap = new HashMap<Integer, T>();
        }
        return infoMap;
    }

    /**
     * 
     * @Title: selectInfoMapByIdList
     * @Description: 根据ID列表批量查询数据列表
     * @author ZhangJianyang
     * @param idList
     * @return
     */
    @Override
    public Map<Integer, T> selectInfoMapByIdList(List<Integer> idList) {
        Map<Integer, T> infoMap = null;
        if (idList == null || idList.size() == 0) {
            return new HashMap<Integer, T>();
        }
        List<T> list = this.getDao().queryByIds(idList.stream().toArray(Integer[]::new));
        if (list != null && list.size() > 0) {
            infoMap = list.stream().collect(Collectors.toMap(T::getId, item -> item));
        }
        if (infoMap == null) {
            infoMap = new HashMap<Integer, T>();
        }
        return infoMap;
    }

    /**
     * 
     * @Title: selectOne
     * @Description: 通用查询单条记录
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public T selectOne(T entity) {
        return this.getDao().selectOne(entity);
    }
    
    /**
     * 
     * @Title: selectOnlyOne
     * @Description: 通用查询最多只查询一条记录
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public T selectOnlyOne(T entity) {
        return this.getDao().selectOnlyOne(entity);
    }
    
    /**
     * 
     * @Title: selectCombineOne
     * @Description: 通用联合查询单条记录
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public Map<String, Object> selectCombineOne(T entity) {
        return this.getDao().selectCombineOne(entity);
    }

    /**
     * 
     * @Title: selectList
     * @Description: 通用查询列表
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public List<T> selectList(T entity) {
        return this.getDao().selectList(entity);
    }
    
    /**
     * 
     * @Title: selectCombineList
     * @Description: 通用联合查询列表
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public List<Map<String, Object>> selectCombineList(T entity) {
        return this.getDao().selectCombineList(entity);
    }

    /**
     * 
     * @Title: selectInfoMap
     * @Description: 通用字段对象映射查询
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public <F> Map<F, T> selectInfoMap(T entity, Function<T, F> function) {
        Map<F, T> infoMap = null;
        List<T> list = this.getDao().selectList(entity);
        if (list != null && list.size() > 0) {
            infoMap = list.stream().collect(Collectors.toMap(function, item -> item));
        }
        if (infoMap == null) {
            infoMap = new HashMap<F, T>();
        }
        return infoMap;
    }

    /**
     * 
     * @Title: selectListMap
     * @Description: 通用字段对象列表映射查询
     * @author ZhangJianyang
     * @param entity
     * @param function
     * @return
     */
    @Override
    public <F> Map<F, List<T>> selectListMap(T entity, Function<T, F> function) {
        Map<F, List<T>> listMap = null;
        List<T> list = this.getDao().selectList(entity);
        if (list != null && list.size() > 0) {
            // 注意这里需要使用LinkedHashMap保持原有的列表元素顺序
            listMap = list.stream().collect(
                    Collectors.groupingBy(function, LinkedHashMap<F, List<T>>::new, Collectors.toList()));
        }
        if (listMap == null) {
            listMap = new HashMap<F, List<T>>();
        }
        return listMap;
    }

    /**
     * 
     * @Title: queryByCount
     * @Description: 通用查询列表数量
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public int queryByCount(T entity) {
        return this.getDao().queryByCount(entity);
    }
    
    /**
     * 
     * @Title: queryCombineCount
     * @Description: 通用联合查询列表数量
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public int queryCombineCount(T entity) {
        return this.getDao().queryCombineCount(entity);
    }

    /**
     * 
     * @Title: queryByList
     * @Description: 通用分页查询
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public PageInfo<T> queryByList(T entity) {
        return this.getDao().queryByList(entity);
    }
    
    /**
     * 
     * @Title: queryCombineList
     * @Description: 通用分页联合查询
     * @author ZhangJianyang
     * @param entity
     * @return
     */
    @Override
    public PageInfo<Map<String, Object>> queryCombineList(T entity) {
        return this.getDao().queryCombineList(entity);
    }

    /**
     * 
     * @Title: selectSingleList
     * @Description: 查询单个字段列表
     * @author ZhangJianyang
     * @param entity
     * @param distinctFlags
     * @return
     */
    @Override
    public <F> List<F> selectSingleList(T entity, Boolean... distinctFlags) {
        return this.getDao().selectSingleList(entity, distinctFlags);
    }

    /**
     * 
     * @Title: selectMultipleList
     * @Description: 查询多个字段列表
     * @author ZhangJianyang
     * @param entity
     * @param distinctFlags
     * @return
     */
    @Override
    public List<Map<String, Object>> selectMultipleList(T entity, Boolean... distinctFlags) {
        return this.getDao().selectMultipleList(entity, distinctFlags);
    }

    /**
     * 
     * @Title: selectKeyValueList
     * @Description: 查询KEY以及VALUE映射列表
     * @author ZhangJianyang
     * @param entity
     * @param distinctFlags
     * @return
     */
    @Override
    public List<Map<String, Object>> selectKeyValueList(T entity, Boolean... distinctFlags) {
        return this.getDao().selectKeyValueList(entity, distinctFlags);
    }

    /**
     * 
     * @Title: selectGroupByCntList
     * @Description: 指定字段分组查询数量
     * @author ZhangJianyang
     * @param entity
     * @param distinctFlags
     * @return
     */
    @Override
    public <F> List<GroupByCntResultModel<F>> selectGroupByCntList(T entity, Boolean... distinctFlags) {
        return this.getDao().selectGroupByCntList(entity, distinctFlags);
    }

    /**
     * 
     * @Title: selectGroupByCntInfoMap
     * @Description: 查询指定字段分组数量映射信息
     * @author ZhangJianyang
     * @param entity
     * @param distinctFlags
     * @return
     */
    @Override
    public <F> Map<F, Integer> selectGroupByCntInfoMap(T entity, Boolean... distinctFlags) {
        Map<F, Integer> infoMap = null;
        List<GroupByCntResultModel<F>> list = this.getDao().selectGroupByCntList(entity, distinctFlags);
        if (list != null && list.size() > 0) {
            infoMap = list.stream().collect(
                    Collectors.toMap(GroupByCntResultModel<F>::getGroupId, (GroupByCntResultModel<F> item) -> {
                        return item.getSubCnt();
                    }));
        }
        if (infoMap == null) {
            infoMap = new HashMap<F, Integer>();
        }
        return infoMap;
    }

    /**
     * 
     * @Title: add
     * @Description: 添加记录
     * @author ZhangJianyang
     * @param t
     * @throws Exception
     */
    @Override
    public void add(T t) throws Exception {
        this.getDao().add(t);
    }

    /**
     * 
     * @Title: update
     * @Description: 更新记录（只要不为null都进行修改，避免0被识别为空字符串）
     * @author ZhangJianyang
     * @param t
     * @throws Exception
     */
    @Override
    public void update(T t) throws Exception {
        this.getDao().update(t);
    }

    /**
     * 
     * @Title: updateBySelective
     * @Description: 更新记录（只修改只不为空的字段，也就是说null或者空字符串均被忽略）
     * @author ZhangJianyang
     * @param t
     * @throws Exception
     */
    @Override
    public void updateBySelective(T t) throws Exception {
        this.getDao().updateBySelective(t);
    }

    /**
     * 
     * @Title: updateIncludeAll
     * @Description: 
     *               更新记录（对所有字段进行修改，无论是null还是空字符串，注意使用此方法，强烈建议先查询完整数据再进行修改，避免数据丢失
     *               ）
     * @author ZhangJianyang
     * @param t
     * @throws Exception
     */
    @Override
    public void updateIncludeAll(T t) throws Exception {
        this.getDao().updateIncludeAll(t);
    }

    /**
     * 
     * @Title: deleteById
     * @Description: 根据主键删除记录
     * @author ZhangJianyang
     * @param id
     * @throws Exception
     */
    @Override
    public void deleteById(Integer id) throws Exception {
        this.getDao().deleteById(id);
    }

    /**
     * 
     * @Title: deleteByIds
     * @Description: 根据主键数组批量删除记录
     * @author ZhangJianyang
     * @param ids
     * @throws Exception
     */
    @Override
    public void deleteByIds(Integer[] ids) throws Exception {
        this.getDao().deleteByIds(ids);
    }

    /**
     * 
     * @Title: deleteByIdList
     * @Description: 根据主键列表批量删除记录
     * @author ZhangJianyang
     * @param idList
     * @throws Exception
     */
    @Override
    public void deleteByIdList(List<Integer> idList) throws Exception {
        if (idList == null || idList.size() == 0) {
            return;
        }
        this.getDao().deleteByIds(idList.stream().toArray(Integer[]::new));
    }

    /**
     * 
     * @Title: deleteBySelective
     * @Description: 根据属性条件删除记录
     * @author ZhangJianyang
     * @param entity
     * @throws Exception
     */
    @Override
    public void deleteBySelective(T entity) throws Exception {
        this.getDao().deleteBySelective(entity);
    }

    /**
     * 
     * @Title: deleteLogicById
     * @Description: 根据主键逻辑删除记录
     * @author ZhangJianyang
     * @param id
     * @throws Exception
     */
    @Override
    public void deleteLogicById(Integer id) {
        this.getDao().deleteLogicById(id);
    }

    /**
     * 
     * @Title: deleteLogicByIds
     * @Description: 根据主键批量逻辑删除记录
     * @author ZhangJianyang
     * @param ids
     * @throws Exception
     */
    @Override
    public void deleteLogicByIds(Integer[] ids) {
        this.getDao().deleteLogicByIds(ids);
    }

    /**
     * 
     * @Title: deleteLogicByIdList
     * @Description: 根据主键列表批量逻辑删除记录
     * @author ZhangJianyang
     * @param idList
     * @throws Exception
     */
    @Override
    public void deleteLogicByIdList(List<Integer> idList) {
        if (idList == null || idList.size() == 0) {
            return;
        }
        this.getDao().deleteLogicByIds(idList.stream().toArray(Integer[]::new));
    }

    /**
     * 
     * @Title: deleteLogicBySelective
     * @Description: 根据属性条件逻辑删除记录
     * @author ZhangJianyang
     * @param entity
     * @throws Exception
     */
    @Override
    public void deleteLogicBySelective(T entity) throws Exception {
        this.getDao().deleteLogicBySelective(entity);
    }

}